package com.huaxin.hxmodulesystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaxin.hxmodulesystem.dto.ResponseCode;
import com.huaxin.hxmodulesystem.dto.ResponseResult;
import com.huaxin.hxmodulesystem.dto.request.CreateSmsTaskReqDTO;
import com.huaxin.hxmodulesystem.mapper.SmsSendTaskMapper;
import com.huaxin.hxmodulesystem.mapping.SmsSendTaskMapping;
import com.huaxin.hxmodulesystem.models.SmsSendTask;
import com.huaxin.hxmodulesystem.service.SmsSendTaskService;
import com.huaxin.message.sms.tencent.SmsService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
@RequiredArgsConstructor
public class SmsSendTaskServiceImpl extends ServiceImpl<SmsSendTaskMapper, SmsSendTask> implements SmsSendTaskService {
    private final ApplicationContext applicationContext;
    private final SmsSendTaskMapping smsSendTaskMapping;
    private final SmsService smsService;

    /**
     * 创建短信发送任务
     *
     * @param in
     * @return
     */
    @Override
    public ResponseResult<Boolean> createSmsTask(CreateSmsTaskReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }
        if (StringUtils.isBlank(in.getBizId())) {
            return ResponseResult.parameterError(null, "业务ID不能为空");
        }
        if (in.getBizType() == null) {
            return ResponseResult.parameterError(null, "业务类型不能为空");
        }
        if (StringUtils.isBlank(in.getPhone())) {
            return ResponseResult.parameterError(null, "手机号不能为空");
        }
        if (StringUtils.isBlank(in.getTemplateCode())) {
            return ResponseResult.parameterError(null, "模板编号不能为空");
        }

        SmsSendTask entity = smsSendTaskMapping.toEntity(in);
        if (save(entity)) {
            return ResponseResult.ok(true);
        }
        return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "添加失败，请稍后再试！", null);
    }

    @Scheduled(fixedDelay = 30_000) // 每30秒检查一次
    public void processPendingTasks() {
        // 查询待发送且时间已到的任务（最多取100条）
        LambdaQueryWrapper<SmsSendTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SmsSendTask::getSendStatus, SmsSendTask.SendStatus.PENDING)
                .le(SmsSendTask::getNextRetryTime, LocalDateTime.now())
                .last("LIMIT 100");

        List<SmsSendTask> tasks = this.list(wrapper);

        for (SmsSendTask task : tasks) {
            processTask(task);
        }
    }

    private void processTask(SmsSendTask task) {
        try {
            // 更新状态为“发送中”
            task.setSendStatus(SmsSendTask.SendStatus.SENDING);
            this.updateById(task);

            var params = task.getTemplateParams();
            // 调用短信服务
            smsService.sendSms(
                    task.getPhone(),
                    task.getTemplateCode(),
                    task.getTemplateParams().keySet().toArray(new String[0])
            );

            // 成功
            task.setSendStatus(SmsSendTask.SendStatus.SUCCESS);
            task.setFailReason(null);
        } catch (Exception e) {
            int retryCount = task.getRetryCount() + 1;
            if (retryCount >= task.getMaxRetry()) {
                task.setSendStatus(SmsSendTask.SendStatus.FAILED);
                task.setFailReason("重试" + retryCount + "次后仍失败: " + e.getMessage().substring(0, Math.min(500, e.getMessage().length())));
            } else {
                task.setRetryCount(retryCount);
                task.setNextRetryTime(LocalDateTime.now().plusMinutes(retryCount * 5)); // 指数退避
                task.setFailReason("第" + retryCount + "次失败: " + e.getMessage());
            }
        } finally {
            task.setUpdatedAt(LocalDateTime.now());
            this.updateById(task);
        }
    }
}
